package com.nowoe.aop.processor;

import com.nowoe.aop.Advice;
import com.nowoe.aop.Advisor;
import com.nowoe.aop.AdvisorImpl;
import com.nowoe.aop.annotation.Aspect;
import com.nowoe.aop.aspectj.AspectPointcut;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;

/**
 * @author 倚栏听风 2023/9/16 13:56
 */
public class AspectProcessor {

    private static List<Advisor> advisors = new ArrayList<>();

    public static List<Advisor> process(Class<?> tClass) {
        Method[] declaredMethods = tClass.getDeclaredMethods();
        //通知排序
        Arrays.sort(declaredMethods, Comparator.comparing(Method::getName));
        for (Method method : declaredMethods) {
            if (method.isAnnotationPresent(Aspect.class)) {
                Aspect aspect = method.getAnnotation(Aspect.class);
                //切点对象
                AspectPointcut pointcut = new AspectPointcut();
                pointcut.setExpression(aspect.value());
                //获取通知对象
                method.setAccessible(true);
                try {
                    Advice advice = (Advice) method.invoke(null);
                    advisors.add(new AdvisorImpl(advice, pointcut));
                } catch (IllegalAccessException | InvocationTargetException e) {
                    throw new RuntimeException(e);
                }
            }
        }
        return advisors;
    }
}
